package com.codechuan.didi_web.thread;

import com.alibaba.fastjson.JSONObject;
import com.codechuan.didi_web.common.Constant;
import com.codechuan.didi_web.entity.SysCarInfo;
import com.codechuan.didi_web.entity.SysSchedule;
import com.codechuan.didi_web.entity.SysUserAccount;
import com.codechuan.didi_web.entity.SysUserConfig;
import com.codechuan.didi_web.mapper.SysUserOrderMapper;
import com.codechuan.didi_web.mapper.SysUserTokenMapper;
import com.codechuan.didi_web.utils.DiDiHttpUtil;
import org.springframework.data.redis.core.RedisTemplate;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.UUID;

/**
 * @Deprecated 获取订单线程
 */
public class ScheduleThread implements Runnable {

    // 参数账户
    private final String account;
    // 参数redis
    private final RedisTemplate<String, String> redisTemplate;
    // 参数token
    private final String ticket;
    // 参数请求类型 0大厅 1行程
    private final String queryType;
    // 大厅请求接口需要传的body参数
    private final HashMap<String, Object> hashMap;
    // 行程请求解决需要传的行程id
    private final String routeId;
    // 刷新延时
    private final Integer sxNumber;
    // 用户订单数据库
    private final SysUserOrderMapper sysUserOrderMapper;

    // 获取过的订单去重处理
    private final ArrayList<String> acquiredOrders = new ArrayList<>();

    // 规则实体类
    private final SysUserConfig sysUserConfig;

    private final  SysCarInfo sysCarInfo;

    // 行程列表
    ArrayList<SysSchedule> sysSchedules;
    int scheduleCount; // 总行程数
    int scheduleNumber = 0; // 当前执行的第几个

    // 用户token实体类
    private final SysUserTokenMapper sysUserTokenMapper;

    // 构造方法
    public ScheduleThread(String account, RedisTemplate<String, String> redisTemplate,
                          String ticket, HashMap<String, Object> map,
                          SysUserOrderMapper sysUserOrderMapper,
                          SysUserConfig sysUserConfig,
                          SysUserTokenMapper sysUserTokenMapper,
                          ArrayList<SysSchedule> sysSchedules,
                          SysCarInfo sysCarInfo
    ) {
        this.account = account;
        this.redisTemplate = redisTemplate;
        this.ticket = ticket;
        this.queryType = sysUserConfig.getQueryType();
        this.hashMap = map;
        this.routeId = sysUserConfig.getRouteId();
        this.sxNumber = sysUserConfig.getSxNumber();
        this.sysUserOrderMapper = sysUserOrderMapper;
        this.sysUserConfig = sysUserConfig;
        this.sysUserTokenMapper = sysUserTokenMapper;
        this.sysSchedules = sysSchedules;
        this.scheduleCount = sysSchedules.size();
        this.sysCarInfo = sysCarInfo;
    }

    // 判断是否是第一次访问接口
    private int count = 0;
    // dd04加密
    private String dd04;
    // js算法结果
    private String secdd_challenge = "1,com.sdu.didi.psnger|1.0.28||||0||";
    // 认证信息
    private String secdd_authentication = "c9b8d7050edfdbda045b14aa7b5d4db484ec7abb1fc410d6b830385e4199d4e721eb3ed4272eb36b32a9d8887eee556a27437a569101000001000000";
    // 接口返回过来的认证信息和js算法
    private HashMap<String, String> map = null;

    // 生成uuid
    public static String didi_uuid = UUID.randomUUID().toString().replace("-", "");

    @Override
    public void run() {
        // http访问类 使用创建的方式,编码出现资源共享的问题
        DiDiHttpUtil diDiHttpUtil = new DiDiHttpUtil();
        // 获取车辆信息
        System.out.println(account + "此人的车辆信息是:" + sysCarInfo);
        // 获取当前时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr1 = sdf.format(new Date());
        while (true) {
            String dateStr2 = sdf.format(new Date());
            // 解析为Date对象
            Date date1;
            Date date2;
            try {
                date1 = sdf.parse(dateStr1);
                date2 = sdf.parse(dateStr2);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            // 计算两个日期的差值（毫秒数）
            long diff = date2.getTime() - date1.getTime();
            // 将差值转换为秒
            long diffSeconds = diff / 1000 % 60;
            if (!String.valueOf(sysUserConfig.getSxJg()).equals("0")  && !String.valueOf(sysUserConfig.getSxTz()).equals(0)){
                if (diffSeconds >= sysUserConfig.getSxJg())
                {
                    System.out.println("开始停止" + sdf.format(new Date()));
                    // 停止
                    try {
                        Thread.sleep(sysUserConfig.getSxTz() * 1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    // 重新赋值时间
                    dateStr1 = sdf.format(new Date());
                }
            }
            long threadId = Thread.currentThread().getId();
            // 判断对象是否存在,不能重复创建避免堆数据不一样
            SysUserAccount anotherObj = Constant.objectMap.get(threadId);
            if (anotherObj == null) {
                Constant.objectMap.computeIfAbsent(threadId, id -> new SysUserAccount(account));
            }

            // 判断当前执行的次数是否大于总次数
            if (scheduleNumber >= scheduleCount)
                scheduleNumber = 0;

            // 判断是行程请求还是大厅请求,大厅请求
            try {
                if (dd04 == null) {
                    String url = "https://api.udache.com/gulfstream/hermesapi/v2/driver/dSfcDriverList?session_id=0&route_id=" + sysSchedules.get(scheduleNumber).getRouteId()
                            + "&page_type=&page_index=0&session_id=0&access_key_id=2&app_version=6.8.12&ddfp=" + didi_uuid + "&token=" + URLEncoder.encode(ticket);
                    dd04 = diDiHttpUtil.getDD04(URLEncoder.encode(url), "");
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            if (count == 0) {
                submitQuery(diDiHttpUtil, anotherObj, sysCarInfo);
                // 获取执行js算法后请求接口返回过来的auth和challenge
                secdd_authentication = map.get("secdd_authentication");
                secdd_challenge = map.get("secdd_challenge");
                count++;
            }
            if (map != null) {
                submitQuery(diDiHttpUtil, anotherObj, sysCarInfo);
                // 判断是否是异常处理如果是 重新获取一次js算法 challenge和auth全部使用默认的
                if (map.get("error") != null) {
                    count = 0;
                    secdd_authentication = map.get("secdd_authentication");
                    secdd_challenge = map.get("secdd_challenge");
                }
            }
            // 判断是否结束线程
            String value = redisTemplate.opsForValue().get(account);
            assert value != null;
            if (value.split(":")[1].equals("0")) {
                System.out.println("线程结束了!");
                return;
            }
            try {
                Thread.sleep(sxNumber);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            scheduleNumber++;

        }
    }


    /**
     * @param diDiHttpUtil 滴滴请求工具类
     * @param anotherObj   用户实体类
     * @Deprecated 通过判断类型调用不同的接口
     */
    private void submitQuery(DiDiHttpUtil diDiHttpUtil, SysUserAccount anotherObj, SysCarInfo carInfo) {


        // 行程刷单接口
        map = diDiHttpUtil.getScheduleOrdrList(ticket, getMD5(String.valueOf(Instant.now().toEpochMilli())),
                dd04, didi_uuid,
                secdd_authentication,
                secdd_challenge,
                sysSchedules.get(scheduleNumber).getRouteId(), anotherObj == null ? account : anotherObj.getKeyNumber(),
                carInfo, acquiredOrders, sysUserOrderMapper, sysUserConfig, redisTemplate);

    }

    /**
     * @param text 时间戳
     * @return 返回加密结果
     * @Deprecated 时间转MD5
     */
    public static String getMD5(String text) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(text.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            System.out.println("e = " + e);
            return null;
        }
    }
}
